<template>
  <div :id="createdId">
    <div class="input-select el-input__inner" v-if="showSelect">
      <div class="tags">
        <el-tag
          v-for="(item, index) in multipleSelectionTags"
          :key="index"
          closable
          @close="handleCloseTag(item)"
          size="small"
          type="info"
          effect="plain"
          >{{ item[keywordKey] || "" }}</el-tag
        >
        <input
          type="text"
          ref="selectInput"
          :value="value"
          :placeholder="placeholderForTag"
          @focus="onfocus"
          @input="changeValue($event.target.value)"
          :disabled="disabled"
        />
        <i
          class="el-icon-arrow-down select-down"
          :class="visible && 'rotate180'"
        ></i>
      </div>
    </div>
    <el-input
      v-else
      :value="value"
      @input="changeValue"
      @focus="onfocus"
      @blur="onblur"
      clearable
      :placeholder="placeholder"
      ref="inputValue"
      :disabled="disabled"
    ></el-input>
    <div
      class="el-picker-panel"
      :style="pStyle"
      v-show="visible"
      ref="elcombogrid"
    >
      <div class="table-container">
        <el-table
          v-loading="listLoading"
          :data="list"
          @row-click="rowClick"
          stripe
          size="mini"
          element-loading-text="Loading"
          ref="comboGridTable"
          fit
          border
          highlight-current-row
          @selection-change="handleSelectionChange"
          @select="handleSingelSelectionChange"
        >
          <el-table-column
            type="selection"
            v-if="showSelect"
            width="55"
            align="center"
          />
          <el-table-column
            v-if="showIndex"
            label="序号"
            type="index"
            align="center"
            width="50"
          ></el-table-column>
          <el-table-column
            v-for="item in columns"
            :type="item.type"
            :key="item.key"
            :label="item.label"
            :prop="item.key"
            :align="item.align"
            :width="item.width"
            :header-align="item.headerAlign"
          >
            <template slot-scope="scope">
              <span>{{ scope.row[item.key] }}</span>
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          v-show="pagination"
          small
          :total="total"
          :page-size="5"
          layout="prev, pager, next, total"
          @current-change="changePage"
        />
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "InputGrid",
  props: {
    placeholder: { type: String },
    value: { type: String },
    requestConfig: {
      default: () => {
        return {
          url: "",
          method: "GET",
        };
      },
    },
    columns: { type: Array },
    panelStyle: { type: String },
    keywordKey: { type: String },
    disabled: { type: Boolean },
    showIndex: { type: Boolean },
    pagination: { type: Boolean, default: true },
    otherParams: { default: () => {} },
    showSelect: { default: false },
  },
  data() {
    return {
      visible: false,
      pStyle: "width:500px",
      list: [],
      total: 0,
      listLoading: true,
      listQuery: {
        pageIndex: 1,
        pageSize: 5,
      },
      keyword: "",
      createdId: "0",
      multipleSelection: [],
      multipleSelectionTags: [],
      placeholderForTag: "",
    };
  },
  mounted() {
    this.createdId = String(new Date().getTime()); // 给个随机id 判断是否clickoutside
    this.placeholderForTag = this.placeholder;
  },
  methods: {
    changePage(cur) {
      this.listQuery.pageIndex = cur;
      this.getList();
    },
    changeValue(val) {
      this.$emit("input", val); // 向上级传送数据
      this.keyword = val;
      this.listQuery.pageIndex = 1;
      this.getList();
    },
    onfocus(el) {
      this.pStyle = this.panelStyle + ";position:absolute;z-index:999999;";
      this.visible = true;
      this.keyword = el.target.value;
      document.removeEventListener("click", this.clickOutFn);
      document.addEventListener("click", this.clickOutFn);
      this.getList();
    },
    onblur(el) {},
    getList() {
      for (let key in this.otherParams) {
        this.listQuery[key] = this.otherParams[key];
      }
      if (this.pagination) {
        this.listQuery[this.keywordKey] = this.keyword;
      } else {
        if (this.keyword) {
          this.listQuery[this.keywordKey] = this.keyword;
        } else {
          this.listLoading = false;
          return; // 如果不分页，无keyword不查询数据（避免大数据量）
        }
      }
      this.listLoading = true;
      this.multipleSelection.length = 0;
      var _this = this;
      if (this.requestConfig.method === "GET") {
        // fetch(this.requestConfig.url, {
        //   method: 'GET',
        //   body: JSON.stringify(this.listQuery)
        // }).then(res => {
        //   _this.listLoading = false
        //   res.json().then(function (obj) {
        //     _this.list = obj.data.records
        //     _this.total = obj.data.total
        //   })
        // })
        this.$axios
          .get(this.requestConfig.url, {
            params: {
              pageIndex: this.listQuery.pageIndex,
              pageSize: this.listQuery.pageSize,
            },
          })
          .then((res) => {
            // console.log(res);
            _this.listLoading = false;
            _this.list = res.data.data.records;
            _this.total = res.data.data.total;
          });
      } else {
        // fetch(this.requestConfig.url, {
        //   method: 'POST',
        //   headers: {'Content-Type': 'application/json;charset=UTF-8'},
        //   body: JSON.stringify(this.listQuery)
        // }).then(res => {
        //   _this.listLoading = false
        //   res.json().then(function (obj) {
        //     _this.list = obj.data.records
        //     _this.total = obj.data.total
        //   })
        // })
        this.$axios.post(this.requestConfig.url, this.listQuery).then((res) => {
          // console.log(res);
          _this.listLoading = false;
          _this.list = res.data.data.records;
          _this.total = res.data.data.total;
        });
      }
      this.$nextTick(() => {
        let ids = this.multipleSelectionTags.map((item) => item.id);
        this.list.length &&
          this.list.forEach((item, index) => {
            if (ids.includes(item.id)) {
              this.$refs.comboGridTable.toggleRowSelection(item);
            }
          });
      });
    },
    rowClick: function (row, column, event) {
      if (this.showSelect) {
        this.$refs.comboGridTable.toggleRowSelection(row);
        this.$emit("input", "");
      } else {
        this.visible = false;
        this.$emit("row-select-event", row, column, event);
        this.$emit("input", row[this.keywordKey]);
        document.removeEventListener("click", this.clickOutFn);
      }
    },
    clickOutFn(e) {
      if (e.path.some((item) => item.id === this.createdId)) return;
      this.visible = false;
      document.removeEventListener("click", this.clickOutFn);
    },
    /**
     * 根据选择与上次的选择进行对比，处理tags
     * todo 聚焦状态。。。触发太多，暂不处理
     */
    handleSelectionChange(val) {
      if (this.multipleSelection.length === 0 && val.length === 0) return;
      if (val.length > this.multipleSelection.length) {
        for (let item of val) {
          if (!this.multipleSelection.some((mitem) => mitem.id === item.id)) {
            let ids = this.multipleSelectionTags.map((item) => item.id);
            !ids.includes(item.id) &&
              (this.multipleSelectionTags =
                this.multipleSelectionTags.concat(item));
          }
        }
      } else {
        for (let item of this.multipleSelection) {
          if (!val.some((mitem) => mitem.id === item.id)) {
            let index = this.multipleSelectionTags.findIndex(
              (mitem) => mitem.id === item.id
            );
            index > -1 && this.multipleSelectionTags.splice(index, 1);
          }
        }
      }
      this.multipleSelection = val;
      this.placeholderForTag = this.multipleSelectionTags.length
        ? ""
        : this.placeholder;
      this.$emit("getSelect", this.multipleSelectionTags);
      // this.$refs.selectInput.focus() todo..
    },
    /**
     * 处理单个复选框选择
     */
    handleSingelSelectionChange() {
      this.$emit("input", "");
    },
    handleCloseTag(item) {
      this.multipleSelectionTags.splice(
        this.multipleSelectionTags.findIndex((mitem) => mitem.id === item.id),
        1
      );
      this.$refs.comboGridTable.toggleRowSelection(item);
    },
  },
};
</script>

<style scoped>
.input-select {
  display: inline-block;
  position: relative;
  width: 100%;
  height: auto;
  min-width: 240px;
  -webkit-appearance: none;
  background-color: #fff;
  background-image: none;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  box-sizing: border-box;
  color: #606266;
  font-size: inherit;
  outline: none;
  padding: 0 15px;
  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
}

.input-select .select-down {
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  transition: all 0.5s;
}

.input-select .select-down.rotate180 {
  transform: translateY(-50%) rotate(180deg);
}

.input-select .tags {
  min-height: 36px;
  flex-wrap: wrap;
  line-height: normal;
  white-space: normal;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
}

.input-select .tags /deep/ .el-tag {
  margin-right: 3px;
  margin-bottom: 1px;
}

.input-select .tags input {
  flex: 1;
  border: none;
  outline: none;
  padding: 0;
  color: #666;
  font-size: 14px;
  appearance: none;
  height: 28px;
  background-color: transparent;
}

.input-select .tags input::-webkit-input-placeholder {
  color: #c0c4cc;
}

.input-select .tags input::-moz-placeholder {
  /* Mozilla Firefox 19+ */
  color: #c0c4cc;
}

.input-select .tags input:-moz-placeholder {
  /* Mozilla Firefox 4 to 18 */
  color: #c0c4cc;
}

.input-select .tags input:-ms-input-placeholder {
  /* Internet Explorer 10-11 */
  color: #c0c4cc;
}
</style>